/*
 * Part of the ACID Project
 * Developed in 2011 by Morgan Taschuk
 */
package acid.plugin.expression.pathfinding;

import acid.network.AcidPath;
import acid.network.ParseCytoscapeGraph;
import acid.plugin.expression.similarity.CalculateGlobalSimilarity;
import cytoscape.CyNode;
import cytoscape.Cytoscape;
import cytoscape.task.Task;
import cytoscape.task.TaskMonitor;
import edu.asu.emit.qyan.alg.control.YenTopKShortestPathsAlg;
import edu.asu.emit.qyan.alg.model.Graph;
import edu.asu.emit.qyan.alg.model.Path;
import edu.asu.emit.qyan.alg.model.abstracts.BaseVertex;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author morgan
 */
public class FindPaths implements Task
{

    private cytoscape.task.TaskMonitor taskMonitor;
    private Graph graph;
    private Collection<AcidPath> set = null;
    private String weightAttribute = null;
    private int source;
    private int target;
    private int k;
    private boolean useExpressionData;

    public FindPaths(String weightAttribute, int source, int target, int k,
            boolean useExpressionData)
    {
        this.weightAttribute = weightAttribute;
        this.source = source;
        this.target = target;
        this.k = k;
        this.useExpressionData = useExpressionData;
    }

    @Override
    public void run() throws ClassCastException
    {
        taskMonitor.setPercentCompleted(-1);
        taskMonitor.setStatus("Parsing Cytoscape graph...");
        graph = ParseCytoscapeGraph.getAcidGraph(weightAttribute);

        taskMonitor.setStatus("Finding paths...");
        YenTopKShortestPathsAlg yenAlg1 = new YenTopKShortestPathsAlg(graph);
        List<Path> shortest_paths_list = yenAlg1.get_shortest_paths(
                graph.get_vertex(source), graph.get_vertex(target), k);

        set = new LinkedList<AcidPath>();

        for (Path p : shortest_paths_list)
        {
            set.add(new AcidPath(graph, p));
        }

        if (useExpressionData)
        {
            taskMonitor.setStatus("Calculating co-expression values...");
            List<CyNode> cynodes = Cytoscape.getCyNodesList();
            ArrayList<String> nodes = new ArrayList<String>();
            for (CyNode cn : cynodes)
            {
                nodes.add(cn.getIdentifier());
            }
            CalculateGlobalSimilarity cgs = new CalculateGlobalSimilarity(nodes);
            for (AcidPath path : set)
            {
                ArrayList<String> identifiers = new ArrayList<String>();
                System.out.println(path.toString()+": ");
                for (BaseVertex bv : path.getVertexList())
                {
                    identifiers.add(new Integer(bv.get_id()).toString());
                }

                path.setExpressionWeight(cgs.pathSimilarity(identifiers));

            }
        }
    }

    public Collection<AcidPath> getSet()
    {
        return set;
    }

    @Override
    public void halt()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setTaskMonitor(TaskMonitor monitor) throws IllegalThreadStateException
    {
        taskMonitor = monitor;
    }

    @Override
    public String getTitle()
    {
        return "Discover pathways";
    }
}
